<?php
/**
 * Created by PhpStorm.
 * User: wxy
 * Date: 2018/11/13
 * Time: 13:59
 */

namespace frontend\modules\resource\logic;

use common\models\BranchResource;
use common\models\HyAudio;
use common\models\HyBook;
use common\models\HyPeriodical;
use common\models\HyPicture;
use common\models\HyResource;
use common\models\HyVideo;
use common\models\ResourceClasses;
use frontend\modules\common\models\BaseHelper;
use frontend\modules\common\models\BaseParam;
use frontend\modules\common\models\ExcelReader;
use frontend\modules\resource\models\HyAudioSearch;
use frontend\modules\resource\models\HyBookSearch;
use frontend\modules\resource\models\HyPeriodicalSearch;
use frontend\modules\resource\models\HyPictureSearch;
use frontend\modules\resource\models\HyVideoSearch;
use Yii;
use yii\db\ActiveRecord;
use yii\helpers\ArrayHelper;
use yii\web\NotFoundHttpException;


class ResourceLogic
{
    /**
     * @param $type
     * @return HyAudioSearch|HyBookSearch|HyPeriodicalSearch|HyPictureSearch|HyVideoSearch
     * @throws \yii\base\ExitException
     */
    public function getResourceModelSearch($type)
    {
        switch ($type) {
            case 1://图书
                $searchModel = new HyBookSearch();
                break;
            case 2://期刊
                $searchModel = new HyPeriodicalSearch();
                break;
            case 3://图片
                $searchModel = new HyPictureSearch();
                break;
            case 4://音频
                $searchModel = new HyAudioSearch();
                break;
            case 5://视频
                $searchModel = new HyVideoSearch();
                break;
            default:
                BaseHelper::Error('无效的分类');
        }

        return $searchModel;

    }

    /**
     * @param $type
     * @param int $id
     * @return HyAudio|HyBook|HyPeriodical|HyPicture|HyVideo|null
     * @throws \yii\base\ExitException
     */
    public function getResourceModel($type, $id = 0)
    {
        switch ($type) {
            case 1://图书
                $Model = new HyBook();
                break;
            case 2://期刊
                $Model = new HyPeriodical();
                break;
            case 3://图片
                $Model = new HyPicture();
                break;
            case 4://音频
                $Model = new HyAudio();
                break;
            case 5://视频
                $Model = new HyVideo();
                break;
            default:
                BaseHelper::Error('无效的分类');
                break;
        }
        if ($id && is_numeric($id)) {
            if (($model = $Model::findOne($id)) !== null) {
                return $model;
            }
            BaseHelper::Error('无效的id');
        }

        return $Model;

    }


    /**
     * @param ActiveRecord $model
     * @param $type
     * @param int $is_self
     * @return bool
     * @throws NotFoundHttpException
     * @throws \yii\base\ExitException
     */
    public function createResource(ActiveRecord $model, $type, $is_self = 0)
    {
        $data = Yii::$app->request->post();
        unset($data['_csrf-frontend']);
        $data = array_shift($data);
        if (empty($data))
            BaseHelper::Error('数据有误');
        //存主表 生成编码  存资源表
        $resource = (new HyResource());
        $resource->type = $type;
        $resource->res_title = $data['res_title'];
        $resource->type = $type;
        $resource->save();

        $data['res_id'] = $resource->primaryKey;
        $data['is_self'] = $is_self;


        if ($model->load($data, '') && $model->save()) {
            if ($is_self) {
                $model = (new BranchResource());
                $model->res_id = $resource->primaryKey;
                $model->res_title = $data['res_title'];
                $model->type = $type;
                $model->br_id = $is_self;
                $model->save();

            }
            return true;
        }
        return false;

    }


    /**
     *
     * 获取唯一code
     * 形如 B20180106000001
     * @param $type
     * @return string
     * @throws NotFoundHttpException
     *
     */
    protected function _resCode($type)
    {
        switch ($type) {
            case 1://图书
                $str = 'B';
                break;
            case 2://期刊
                $str = 'P';
                break;
            case 3://图片
                $str = 'T';
                break;
            case 4://音频
                $str = 'A';
                break;
            case 5://视频
                $str = 'V';
                break;
            default:
                throw new NotFoundHttpException('无效的分类');
                break;
        }
        $str .= $this->_resourceCode();
        return $str;
    }

    /**
     * @param int $cateId
     * @return array
     */
    public static function classesMap($cateId = 0)
    {
        $res = (new ResourceClasses())->find()
            ->select('id,title')
            ->where(['pid' => $cateId, 'status' => 1])
            ->asArray()
            ->all();

        $data = ArrayHelper::map($res, 'id', 'title');
        return $data;
    }


    /**
     * 获取唯一编码形如 20180106000001
     * @return string
     */
    private function _resourceCode()
    {
        $redis = Yii::$app->redis;
        $time = $redis->get('resource_time');

        //时间不是今天  则重置num=1;
        if (empty($time) || (strtotime($time) != strtotime('today'))) {

            $redis->watch('resource_time');//用事务保证只重置一次
            $redis->multi();
            $redis->set('resource_time', date('Y-m-d'));
            $redis->set('resource_num', 1);
            $res = $redis->exec();
            if ($res) {
                $num = 1;
            } else {//已经重置过了
                $num = $redis->incr('resource_num');
            }
        } else {//num++
            $num = $redis->incr('resource_num');
        }
        //补全前面
        $defaultLength = 6;
        $length = $defaultLength - strlen($num);

        if ($length > 0) {
            $head = substr('000000', 0, $length);
            $num = $head . $num;
        }

        return date('Ymd') . $num;
    }


    /**
     * 读取信息
     * @param $path
     * @param $type
     * @return int
     * @throws NotFoundHttpException
     * @throws \PHPExcel_Exception
     * @throws \PHPExcel_Reader_Exception
     * @throws \yii\base\ExitException
     * @throws \yii\db\Exception
     */
    public function ImportData($path, $type)
    {

        if (!file_exists($path)) {
            BaseHelper::Error('文件不存在');
        }
        //设置脚本运行时间（单位：秒） 0-没有时间限制
        set_time_limit(0);
        //memory_limit-设定一个脚本所能够申请到的最大内存字节数
        ini_set('memory_limit', '2048M');

        $excelHeader = $this->_getExcelHeader($type);
        $data = (new ExcelReader())->NormalReadExcel($path, $excelHeader);

        unset($data[1]);
        //校验字段是否都符合todo
        $num = $this->_insertUserData($data, $type);
        return $num;
    }

    /**
     * @param $data
     * @param $type
     * @return int
     * @throws NotFoundHttpException
     * @throws \yii\base\ExitException
     * @throws \yii\db\Exception
     */

    private function _insertUserData($data, $type)
    {
        $num = 0;//计数器
        if (empty($data) || !is_array($data)) {
            return $num;
        }
        $transaction = Yii::$app->db->beginTransaction();
        try {

            //插入主表  返回res——id
            foreach ($data as $k => $v) {

                //重复资源跳过
                $model = $this->getResourceModel($type);
//                if ($v['url'] && $model->find()->where(['url' => $v['url']])->count()) {
//                    continue;
//                }
                //以后注释  测试自动生成
                $v['res_code'] = $this->_resCode($type);
                //存主表 生成编码  存资源表
                $resource = (new HyResource());
                $resource->type = $type;
                $resource->res_title = $v['res_title'];
                $resource->type = $type;
                $resource->code = $v['res_code'];
                $resource->save();

                $v['res_id'] = $resource->primaryKey;

                //获取分类  todo 分类从redis里取更快
                $pid = ResourceClasses::find()->select('pid')->where(['id' => $v['cat_id2']])->asArray()->one();
                if (empty($pid)) {
                    //移除最后一条主表 失败记录
                    HyResource::deleteAll(['id' => $v['res_id']]);
                    $position = $k + 1;
                    throw new \yii\db\Exception('新增资源：' . $num . '条，第' . $position . '条数据导入失败：资源分类号错误');
                }
                $v['cat_id'] = $pid['pid'];

                if ($model->load($v, '') && $model->save()) {
                    $num++;
                } else {
                    //移除最后一条主表 失败记录
                    HyResource::deleteAll(['id' => $v['res_id']]);
                    $res = $model->getFirstErrors() ?: '数据格式不合规范';
                    if (is_array($res)) {
                        $kkk = array_values($res);
                        $res = $kkk[0];
                    }
                    $position = $k + 1;
                    throw new \yii\db\Exception('新增资源：' . $num . '条，第' . $position . '条数据导入失败：' . $res);
                }
            }
            $transaction->commit();
            return $num;
        } catch (\yii\db\Exception $e) {

            $transaction->commit();
            BaseHelper::Error($e->getMessage());
        }
    }

    /**
     * @param $type
     * @return array
     * @throws NotFoundHttpException
     */
    protected function _getExcelHeader($type)
    {
        switch ($type) {
            case 1://图书
                $ExcelHeader = BaseParam::$bookExcelHeader;
                break;
            case 2://期刊
                $ExcelHeader = BaseParam::$periodicalExcelHeader;
                break;
            case 3://图片
                $ExcelHeader = BaseParam::$pictureExcelHeader;
                break;
            case 4://音频
                $ExcelHeader = BaseParam::$audioExcelHeader;
                break;
            case 5://视频
                $ExcelHeader = BaseParam::$videoExcelHeader;
                break;
            default:
                throw new NotFoundHttpException('无效的分类');
                break;
        }
        return $ExcelHeader;

    }


}